from PyQt5.QtWidgets import QMainWindow, QWidget, QDesktopWidget, QSplitter, QHBoxLayout, QVBoxLayout, QLabel, QMessageBox
from PyQt5.QtGui import QIcon, QMouseEvent, QCursor
from PyQt5.QtCore import pyqtSignal, QEvent, QPoint
from PyQt5.Qt import Qt
import os

from .menu_bar import MenuBar
from .status_bar import StatusBar
from .theme_manager import ThemeManager
from .left_sidebar import LeftSideBar
from .file_explorer import FileExplorer
from .workspace import Workspace
from .terminal import Terminal
from .right_panel import RightPanel
from .global_search import SearchWindow
from .run_manager import RunManager


class WindowBorderControl(QLabel):
    """窗口边框控制类，用于拖拽缩放窗口"""
    
    def __init__(self, parent, position):
        super().__init__(parent)
        self.position = position  # 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'
        self.main_window = parent
        self.setMouseTracking(True)
        self.setup_border()
    
    def setup_border(self):
        """设置边框样式"""
        # 设置不同位置边框的大小
        border_size = 5
        if self.position in ['top', 'bottom']:
            self.setMinimumHeight(border_size)
            self.setMaximumHeight(border_size)
        elif self.position in ['left', 'right']:
            self.setMinimumWidth(border_size)
            self.setMaximumWidth(border_size)
        else:  # 角位置
            self.setMinimumSize(border_size, border_size)
            self.setMaximumSize(border_size, border_size)
        
        # 设置鼠标样式
        self.setup_cursor()
        
        # 透明背景，只在悬停时显示
        self.setStyleSheet("""
            WindowBorderControl {
                background-color: transparent;
            }
            WindowBorderControl:hover {
                background-color: rgba(255, 255, 255, 0.1);
            }
        """)
    
    def setup_cursor(self):
        """设置鼠标样式"""
        cursors = {
            'top': Qt.SizeVerCursor,
            'bottom': Qt.SizeVerCursor,
            'left': Qt.SizeHorCursor,
            'right': Qt.SizeHorCursor,
            'top-left': Qt.SizeFDiagCursor,
            'top-right': Qt.SizeBDiagCursor,
            'bottom-left': Qt.SizeBDiagCursor,
            'bottom-right': Qt.SizeFDiagCursor
        }
        self.setCursor(QCursor(cursors[self.position]))
    
    def mousePressEvent(self, event):
        """鼠标按下事件"""
        if event.button() == Qt.LeftButton:
            self.main_window.drag_resize_start(self.position, event.globalPos())
        super().mousePressEvent(event)
    
    def mouseMoveEvent(self, event):
        """鼠标移动事件"""
        if self.main_window.drag_resizing:
            self.main_window.drag_resize_update(event.globalPos())
        super().mouseMoveEvent(event)
    
    def mouseReleaseEvent(self, event):
        """鼠标释放事件"""
        if event.button() == Qt.LeftButton:
            self.main_window.drag_resize_stop()
        super().mouseReleaseEvent(event)

class MainWindow(QMainWindow):
    window_state_changed = pyqtSignal(Qt.WindowStates)
    
    def __init__(self, folder_path=None, file_path=None):
        super().__init__()
        self.theme_manager = ThemeManager()
        
        # 窗口拖动相关变量
        self.dragging = False
        self.drag_position = QPoint()
        
        # 窗口缩放相关变量
        self.drag_resizing = False
        self.drag_resize_position = None
        self.drag_resize_start_pos = QPoint()
        self.drag_resize_start_geometry = None
        
        # 保存启动时的文件夹路径和文件路径
        self.startup_folder_path = folder_path
        self.startup_file_path = file_path
        
        self.setup_window()
        self.setup_ui()
        self.setup_styles()
        
        # 启用鼠标跟踪
        self.setMouseTracking(True)
        
        # 如果提供了文件夹路径，启动时加载该文件夹
        if self.startup_folder_path:
            self.load_startup_folder()
        
        # 如果提供了文件路径，启动时打开该文件
        if self.startup_file_path:
            self.load_startup_file()
    
    def setup_window(self):
        """设置窗口基本属性"""
        self.setWindowTitle("CodeIdea")
        
        # 窗口大小
        self.resize(1200, 720)
        
        # 居中位置
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2)
        
        # 无边框窗口
        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
        
        # 设置窗口图标
        icon_path = self.get_resource_path("icons/ide.ico")
        self.setWindowIcon(QIcon(icon_path))
    
    def changeEvent(self, event):
        super().changeEvent(event)
        if event.type() == QEvent.WindowStateChange:
            self.window_state_changed.emit(self.windowState())
    
    def setup_ui(self):
        """设置用户界面"""
        # 设置菜单栏
        self.menu_bar = MenuBar(self)
        self.setMenuBar(self.menu_bar)
        
        # 设置状态栏
        self.status_bar = StatusBar(self)
        self.setStatusBar(self.status_bar)
        
        # 设置运行管理器
        self.run_manager = RunManager(self)
        
        # 创建主容器
        self.main_container = QWidget()
        main_layout = QVBoxLayout(self.main_container)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)
        
        # 添加上边框
        self.top_border = WindowBorderControl(self, 'top')
        main_layout.addWidget(self.top_border)
        
        # 创建中央内容区域
        content_widget = QWidget()
        content_layout = QHBoxLayout(content_widget)
        content_layout.setContentsMargins(0, 0, 0, 0)
        content_layout.setSpacing(0)
        
        # 添加左边框
        self.left_border = WindowBorderControl(self, 'left')
        content_layout.addWidget(self.left_border)
        
        # 主内容区域
        self.content_area = QWidget()
        content_area_layout = QHBoxLayout(self.content_area)
        content_area_layout.setContentsMargins(0, 0, 0, 0)
        content_area_layout.setSpacing(0)
        
        # 左侧边栏（固定宽度50px）
        self.left_sidebar = LeftSideBar(self)
        
        # 资源管理器（紧邻侧边栏，可调整宽度）
        self.file_explorer = FileExplorer(self)
        self.file_explorer.setMinimumWidth(200)  # 最小宽度
        self.file_explorer.setMaximumWidth(600)  # 最大宽度
        
        # 工作区
        self.workspace = Workspace(self)
        
        # 终端输出
        self.terminal = Terminal(self)
        self.terminal.setMinimumHeight(150)
        
        # 垂直分割器：工作区 + 终端
        self.vertical_splitter = QSplitter(Qt.Vertical)
        self.vertical_splitter.addWidget(self.workspace)
        self.vertical_splitter.addWidget(self.terminal)
        
        # 设置垂直分割器初始比例（工作区:终端 = 800:0，终端默认隐藏）
        self.vertical_splitter.setSizes([800, 0])
        self.terminal.setVisible(False)  # 默认隐藏终端
        
        # 右侧面板
        self.right_panel = RightPanel(self)
        self.right_panel.setMinimumWidth(200)
        self.right_panel.setMaximumWidth(400)
        
        # 主分割器：侧边栏 + 资源管理器 + 工作区/终端 + 右侧面板
        self.main_splitter = QSplitter(Qt.Horizontal)
        
        # 添加所有组件到主分割器
        self.main_splitter.addWidget(self.left_sidebar)
        self.main_splitter.addWidget(self.file_explorer)
        self.main_splitter.addWidget(self.vertical_splitter)
        self.main_splitter.addWidget(self.right_panel)
        
        # 设置主分割器初始比例：侧边栏50px + 资源管理器350px + 工作区/终端1100px + 右侧面板0px（默认隐藏）
        self.main_splitter.setSizes([50, 350, 1100, 0])
        self.right_panel.setVisible(False)  # 默认隐藏右侧面板
        
        # 设置分割器手柄样式
        self.main_splitter.setStyleSheet("""
            QSplitter::handle {
                background-color: #444;
                width: 1px;
            }
            QSplitter::handle:hover {
                background-color: #666;
            }
        """)
        
        # 垂直分割器样式
        self.vertical_splitter.setStyleSheet("""
            QSplitter::handle {
                background-color: #444;
                height: 1px;
            }
            QSplitter::handle:hover {
                background-color: #666;
            }
        """)
        
        content_area_layout.addWidget(self.main_splitter)
        content_layout.addWidget(self.content_area)
        
        # 添加右边框
        self.right_border = WindowBorderControl(self, 'right')
        content_layout.addWidget(self.right_border)
        
        main_layout.addWidget(content_widget)
        
        # 添加下边框
        self.bottom_border = WindowBorderControl(self, 'bottom')
        main_layout.addWidget(self.bottom_border)
        
        # 添加角控制
        self.top_left_corner = WindowBorderControl(self, 'top-left')
        self.top_left_corner.setParent(self.main_container)
        self.top_left_corner.move(0, 0)
        
        self.top_right_corner = WindowBorderControl(self, 'top-right')
        self.top_right_corner.setParent(self.main_container)
        
        self.bottom_left_corner = WindowBorderControl(self, 'bottom-left')
        self.bottom_left_corner.setParent(self.main_container)
        
        self.bottom_right_corner = WindowBorderControl(self, 'bottom-right')
        self.bottom_right_corner.setParent(self.main_container)
        
        # 设置中央窗口
        self.setCentralWidget(self.main_container)
        
        # 连接侧边栏信号
        self.connect_sidebar_signals()
        
        # 连接工作区标签页切换信号
        self.connect_workspace_signals()
        
        # 为所有子组件添加鼠标事件拦截，确保窗口可以拖动
        self.setup_window_dragging()
    
    def get_resource_path(self, relative_path):
        """获取资源文件的绝对路径，支持打包后的资源访问"""
        # 首先尝试从当前工作目录查找
        base_path = os.path.dirname(os.path.abspath(__file__))
        resource_path = os.path.join(base_path, "..", "resources", relative_path)
        
        if os.path.exists(resource_path):
            return resource_path
        
        # 如果找不到，尝试从打包后的资源目录查找
        resource_path = os.path.join("resources", relative_path)
        if os.path.exists(resource_path):
            return resource_path
        
        # 如果都找不到，返回原始路径（打包工具可能会处理）
        return os.path.join("resources", relative_path)
    
    def connect_sidebar_signals(self):
        """连接侧边栏信号"""
        # 连接文件浏览器按钮点击事件
        self.left_sidebar.file_explorer_toggled.connect(self.on_file_explorer_toggled)
        
        # 连接搜索按钮点击事件
        self.left_sidebar.search_clicked.connect(self.openGlobalSearch)
        
        # 连接资源管理器文件双击信号
        if hasattr(self, 'file_explorer'):
            self.file_explorer.file_double_clicked.connect(self.on_file_double_clicked)
    
    def connect_workspace_signals(self):
        """连接工作区信号"""
        # 连接标签页切换信号
        if hasattr(self, 'workspace') and hasattr(self.workspace, 'tab_widget'):
            self.workspace.tab_widget.currentChanged.connect(self.on_tab_changed)
    
    def on_tab_changed(self, index):
        """标签页切换事件"""
        # 获取当前文件路径并在状态栏显示
        if hasattr(self, 'workspace') and hasattr(self, 'status_bar'):
            file_path = self.workspace.get_current_file_path()
            self.status_bar.set_file_path(file_path or "")
    
    def on_file_explorer_toggled(self, visible):
        """文件浏览器按钮切换事件"""
        # 获取当前所有组件的尺寸
        current_sizes = self.main_splitter.sizes()
        
        # 如果隐藏资源管理器
        if not visible:
            # 保存当前资源管理器宽度并分配给工作区
            explorer_width = current_sizes[1]
            new_sizes = [
                current_sizes[0],  # 侧边栏宽度不变
                0,                 # 隐藏资源管理器
                current_sizes[2] + explorer_width,  # 工作区完全扩充
                current_sizes[3]   # 右侧面板宽度不变
            ]
        else:
            # 显示资源管理器，恢复之前的宽度
            # 从工作区宽度中分配出之前保存的资源管理器宽度
            explorer_width = 350  # 默认宽度
            available_width = current_sizes[2] - explorer_width
            if available_width < 500:  # 确保工作区有最小宽度
                available_width = 500
                explorer_width = current_sizes[2] - available_width
            
            new_sizes = [
                current_sizes[0],  # 侧边栏宽度不变
                explorer_width,    # 资源管理器宽度
                available_width,   # 工作区宽度
                current_sizes[3]   # 右侧面板宽度不变
            ]
        
        # 应用新的尺寸
        self.main_splitter.setSizes(new_sizes)
        # 切换资源管理器的可见性
        self.file_explorer.setVisible(visible)
    
    def on_file_double_clicked(self, file_path):
        """资源管理器文件双击事件"""
        if hasattr(self, 'workspace'):
            if self.workspace.open_file(file_path):
                if hasattr(self, 'status_bar'):
                    filename = os.path.basename(file_path)
                    self.status_bar.showMessage(f"已打开文件: {filename}")
    
    def setup_window_dragging(self):
        """设置窗口拖动功能"""
        # 为所有子组件安装事件过滤器
        for child in self.findChildren(QWidget):
            child.installEventFilter(self)
        
        # 为中央组件安装事件过滤器
        self.centralWidget().installEventFilter(self)
    
    def eventFilter(self, obj, event):
        """事件过滤器 - 只对特定区域生效的窗口拖动"""
        # 只对侧边栏组件处理拖动事件
        if obj == self.left_sidebar:
            if event.type() == QEvent.MouseButtonPress:
                if event.button() == Qt.LeftButton:
                    self.dragging = True
                    self.drag_position = event.globalPos() - self.pos()
                    return True
            elif event.type() == QEvent.MouseMove:
                if self.dragging and (event.buttons() & Qt.LeftButton):
                    self.move(event.globalPos() - self.drag_position)
                    return True
            elif event.type() == QEvent.MouseButtonRelease:
                if event.button() == Qt.LeftButton:
                    self.dragging = False
                    return True
        
        return super().eventFilter(obj, event)
    
    def drag_resize_start(self, position, global_pos):
        """开始拖拽缩放"""
        self.drag_resizing = True
        self.drag_resize_position = position
        self.drag_resize_start_pos = global_pos
        self.drag_resize_start_geometry = self.geometry()
    
    def drag_resize_update(self, global_pos):
        """更新拖拽缩放位置"""
        if not self.drag_resizing or not self.drag_resize_start_geometry:
            return
        
        # 计算鼠标移动的偏移量
        delta = global_pos - self.drag_resize_start_pos
        
        # 获取初始几何信息
        x, y, w, h = self.drag_resize_start_geometry.getRect()
        
        # 根据拖拽位置调整窗口大小和位置
        if self.drag_resize_position == 'top':
            new_height = max(self.minimumHeight(), h - delta.y())
            self.setGeometry(x, y + (h - new_height), w, new_height)
        elif self.drag_resize_position == 'bottom':
            new_height = max(self.minimumHeight(), h + delta.y())
            self.setGeometry(x, y, w, new_height)
        elif self.drag_resize_position == 'left':
            new_width = max(self.minimumWidth(), w - delta.x())
            self.setGeometry(x + (w - new_width), y, new_width, h)
        elif self.drag_resize_position == 'right':
            new_width = max(self.minimumWidth(), w + delta.x())
            self.setGeometry(x, y, new_width, h)
        elif self.drag_resize_position == 'top-left':
            new_width = max(self.minimumWidth(), w - delta.x())
            new_height = max(self.minimumHeight(), h - delta.y())
            self.setGeometry(x + (w - new_width), y + (h - new_height), new_width, new_height)
        elif self.drag_resize_position == 'top-right':
            new_width = max(self.minimumWidth(), w + delta.x())
            new_height = max(self.minimumHeight(), h - delta.y())
            self.setGeometry(x, y + (h - new_height), new_width, new_height)
        elif self.drag_resize_position == 'bottom-left':
            new_width = max(self.minimumWidth(), w - delta.x())
            new_height = max(self.minimumHeight(), h + delta.y())
            self.setGeometry(x + (w - new_width), y, new_width, new_height)
        elif self.drag_resize_position == 'bottom-right':
            new_width = max(self.minimumWidth(), w + delta.x())
            new_height = max(self.minimumHeight(), h + delta.y())
            self.setGeometry(x, y, new_width, new_height)
    
    def drag_resize_stop(self):
        """停止拖拽缩放"""
        self.drag_resizing = False
        self.drag_resize_position = None
        self.drag_resize_start_geometry = None
    
    def resizeEvent(self, event):
        """窗口大小改变事件"""
        super().resizeEvent(event)
        self.update_corner_positions()
    
    def update_corner_positions(self):
        """更新角控制位置"""
        width = self.width()
        height = self.height()
        
        # 右上角
        self.top_right_corner.move(width - 5, 0)
        # 左下角
        self.bottom_left_corner.move(0, height - 5)
        # 右下角
        self.bottom_right_corner.move(width - 5, height - 5)
    
    def setup_styles(self):
        """设置窗口样式"""
        # 使用主题管理器加载样式
        stylesheet = self.theme_manager.load_theme('dark')
        if stylesheet:
            self.setStyleSheet(stylesheet)
        else:
            # 如果主题加载失败，使用默认样式
            default_style = """
            QMainWindow {
                background-color: #1a1a1a;
                border: 1px solid #444;
                color: white;
            }
            QLabel {
                color: white;
                background-color: transparent;
            }
            """
            combined_style = default_style + self.menu_bar.get_stylesheet() + self.status_bar.get_stylesheet()
            self.setStyleSheet(combined_style)
    
    def load_startup_folder(self):
        """加载启动时指定的文件夹"""
        import os
        
        # 检查文件夹路径是否存在
        if not os.path.exists(self.startup_folder_path):
            print(f"警告：指定的文件夹路径不存在：{self.startup_folder_path}")
            return
        
        # 确保路径是目录
        if not os.path.isdir(self.startup_folder_path):
            print(f"警告：指定的路径不是文件夹：{self.startup_folder_path}")
            return
        
        # 加载文件夹到资源管理器
        if hasattr(self, 'file_explorer'):
            # 确保资源管理器可见
            if hasattr(self, 'left_sidebar'):
                self.left_sidebar.toggle_file_explorer(True)
            
            # 加载文件夹
            self.file_explorer.load_folder(self.startup_folder_path)
            
            # 更新窗口标题显示当前项目
            folder_name = os.path.basename(self.startup_folder_path)
            self.setWindowTitle(f"CodeIdea - {folder_name}")
            
            # 在状态栏显示加载的项目路径
            if hasattr(self, 'status_bar'):
                self.status_bar.set_file_path(self.startup_folder_path)
            
            print(f"已加载项目文件夹：{self.startup_folder_path}")

    def load_startup_file(self):
        """加载启动时指定的文件"""
        import os
        
        # 检查文件路径是否存在
        if not os.path.exists(self.startup_file_path):
            print(f"警告：指定的文件路径不存在：{self.startup_file_path}")
            return
        
        # 确保路径是文件
        if not os.path.isfile(self.startup_file_path):
            print(f"警告：指定的路径不是文件：{self.startup_file_path}")
            return
        
        # 获取文件所在目录
        file_dir = os.path.dirname(self.startup_file_path)
        
        # 如果提供了文件夹路径，确保文件目录与文件夹路径一致
        if self.startup_folder_path and file_dir != self.startup_folder_path:
            print(f"警告：文件路径与文件夹路径不一致，将使用文件所在目录：{file_dir}")
            self.startup_folder_path = file_dir
        
        # 如果没有提供文件夹路径，使用文件所在目录
        if not self.startup_folder_path:
            self.startup_folder_path = file_dir
        
        # 先加载文件夹到资源管理器
        if hasattr(self, 'file_explorer') and self.startup_folder_path:
            # 确保资源管理器可见
            if hasattr(self, 'left_sidebar'):
                self.left_sidebar.toggle_file_explorer(True)
            
            # 加载文件夹
            self.file_explorer.load_folder(self.startup_folder_path)
            
            # 更新窗口标题显示当前项目
            folder_name = os.path.basename(self.startup_folder_path)
            self.setWindowTitle(f"CodeIdea - {folder_name}")
            
            # 在状态栏显示加载的项目路径
            if hasattr(self, 'status_bar'):
                self.status_bar.set_file_path(self.startup_folder_path)
        
        # 打开文件
        if hasattr(self, 'workspace'):
            if self.workspace.open_file(self.startup_file_path):
                # 更新状态栏显示打开的文件
                if hasattr(self, 'status_bar'):
                    filename = os.path.basename(self.startup_file_path)
                    self.status_bar.showMessage(f"已打开文件: {filename}")
                
                print(f"已打开文件：{self.startup_file_path}")
            else:
                print(f"打开文件失败：{self.startup_file_path}")
    
    def openGlobalSearch(self):
        """打开全局搜索窗口"""
        # 获取当前项目根目录 - 优先使用文件资源管理器的当前目录
        root_directory = ""
        
        # 首先检查文件资源管理器是否有当前项目目录
        if hasattr(self, 'file_explorer') and hasattr(self.file_explorer, 'current_folder') and self.file_explorer.current_folder:
            root_directory = self.file_explorer.current_folder
        # 如果没有，检查启动时传入的文件夹路径
        elif hasattr(self, 'startup_folder_path') and self.startup_folder_path:
            root_directory = self.startup_folder_path
        # 如果都没有，使用默认项目目录
        else:
            current_dir = os.path.dirname(os.path.abspath(__file__))
            root_directory = os.path.join(current_dir, "..")
        
        if not root_directory or not os.path.exists(root_directory):
            QMessageBox.warning(self, "警告", "请先打开项目文件夹")
            return
        
        # 创建搜索窗口
        self.search_window = SearchWindow(self, root_directory)
        self.search_window.show()
        
        # 更新文件资源管理器的项目名称显示
        if hasattr(self, 'file_explorer'):
            self.file_explorer.update_project_name()

if __name__ == "__main__":
    from PyQt5.QtWidgets import QApplication
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()